package wangmin.common.region;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;

/**
 * Created by wm on 2017/4/13.
 */
public class Region implements Comparable<Region> {
	public static boolean isListEmpty(List<?> list) {
		return list == null || list.isEmpty();
	}

	private long id;
	private List<Region> sub; // 如果引用为null, 代表为叶子节点

	public Region() {
	}
	public Region(long id) {
		this.id = id;
	}
	public Region(long id, List<Region> sub) {
		this.id = id;
		this.sub = sub;
	}
	@Override
	public int compareTo(Region o) {
		if (this.id < o.id)
			return -1;
		else if (this.id > o.id)
			return 1;
		else
			return 0;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public List<Region> getSub() {
		return sub;
	}
	public void setSub(List<Region> sub) {
		this.sub = sub;
	}
	private static void generateCompressStrSB(List<Region> l, StringBuilder sb) {
		Collections.sort(l);
		for (int idx = 0; idx < l.size(); ++idx) {
			Region r = l.get(idx);
			sb.append(r.getId());
			if (!isListEmpty(r.getSub())) {
				sb.append('(');
				generateCompressStrSB(r.getSub(), sb);
				sb.append(')');
			}
			if (idx != l.size() - 1)
				sb.append(',');
		}
	}

	private static class RegionTempResult {
		public List<Region> l;
		public int idx;

		public RegionTempResult(List<Region> l, int idx) {
			this.l = l;
			this.idx = idx;
		}
	}

	private static class ReadIdAndIndex {
		public final int id;
		public final int index;

		public ReadIdAndIndex(int id, int index) {
			this.id = id;
			this.index = index;
		}
	}

	private static ReadIdAndIndex readRegionIdFromCharArray(char[] ca, int index) {
		int id = 0;
		while (index < ca.length && ca[index] >= '0' && ca[index] <= '9') {
			id = id * 10 + (ca[index] - '0');
			++index;
		}
		return new ReadIdAndIndex(id, index);
	}
	private static Region.RegionTempResult buildFromCompressCharArray(char[] ca, int idx) {
		List<Region> l = new ArrayList<>();
		while (true) {
			ReadIdAndIndex readIdAndIndex = readRegionIdFromCharArray(ca, idx);
			idx = readIdAndIndex.index;
			Region r = new Region(readIdAndIndex.id);
			l.add(r);
			while (true) {
				if (idx >= ca.length || ')' == ca[idx]) {
					return new Region.RegionTempResult(l, idx);
				} else if (',' == ca[idx]) {
					++idx;
					break;
				} else if ('(' == ca[idx]) {
					++idx;
					Region.RegionTempResult rtr = buildFromCompressCharArray(ca, idx);
					r.setSub(rtr.l);
					idx = rtr.idx + 1; // skip last )
				}
			}
		}
	}
	/**
	 * 将对象生成为压缩字符串
	 **/
	public static String generateCompressStr(List<Region> l) {
		StringBuilder sb = new StringBuilder();
		generateCompressStrSB(l, sb);
		return sb.toString();
	}
	/**
	 * 从压缩字符串生成对象
	 **/
	public static List<Region> buildFromCompressStr(String str) {
		if (StringUtils.isEmpty(str))
			return null;
		Region.RegionTempResult rtr = buildFromCompressCharArray(str.toCharArray(), 0);
		return rtr.l;
	}
	/**
	 * 将json字符串转化为压缩字符串
	 **/
	public static String convertJsonStrToCompressStr(String jsonStr) {
		if (StringUtils.isEmpty(jsonStr))
			return null;
		List<Region> l = JSON.parseArray(jsonStr, Region.class);
		return generateCompressStr(l);
	}
	/**
	 * 将压缩字符串转化为json字符串
	 **/
	public static String convertCompressStrToJsonStr(String compressStr) {
		if (StringUtils.isEmpty(compressStr))
			return null;
		return JSON.toJSONString(buildFromCompressStr(compressStr));
	}
	public static void printAsCompressStr(List<Region> l) {
		System.out.println(generateCompressStr(l));
	}
}
